package com.chen.command;
/**
  * 命令模式把一个请求或者操作封装到一个对象中
  * 命令模式允许系统使用不同的请求把客户端参数化，对请求排队或者记录请求日志，可以提供命令的撤销和恢复功能
  * 命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分隔开，委派给不同的对象
  * 
  * 　命令模式涉及到五个角色，它们分别是：
  * 		客户端(Client)角色：创建一个具体命令(ConcreteCommand)对象并确定其接收者
  * 		命令(Command)角色：声明了一个给所有具体命令类的抽象接口
  * 		具体命令(ConcreteCommand)角色：定义一个接收者和行为之间的弱耦合；实现execute()方法，负责调用接收者的相应操作。execute()方法通常叫做执行方法
  * 		请求者(Invoker)角色：负责调用命令对象执行请求，相关的方法叫做行动方法
  * 		接收者(Receiver)角色：负责具体实施和执行一个请求。任何一个类都可以成为接收者，实施和执行请求的方法叫做行动方法
  * 
  * 命令模式的优点
  * 	更松散的耦合 :  命令模式使得发起命令的对象客户端，和具体实现命令的对象接收者对象完全解耦，也就是说发起命令的对象完全不知道具体实现对象是谁，也不知道如何实现
  * 	更动态的控制 : 命令模式把请求封装起来，可以动态地对它进行参数化、队列化和日志化等操作，从而使得系统更灵活
  * 	很自然的复合命令 : 命令模式中的命令对象能够很容易地组合成复合命令，也就是宏命令，从而使系统操作更简单，功能更强大
  * 	更好的扩展性 : 发起命令的对象和具体的实现完全解耦，因此扩展新的命令只需要实现新的命令对象，在装配的时候，把具体的实现对象设置到命令对象中，然后就可以使用这个命令对象
  * 
  * 
  * 2018-3-19 13:52:02
  * @author jinlong.chen
  */
public class Main {

	public static void main(String[] args) {
		//Main函数便是客户端角色
		
		//接收者(Receiver)角色，执行各种操作
		AudioPlayerReceiver audioPlayerReceiver = new AudioPlayerReceiver();
		
		//抽象出来的命令
		Command playCommand = new PlayCommand(audioPlayerReceiver);
		Command rewindCommand = new RewindCommand(audioPlayerReceiver);
		Command stopCommand = new StopCommand(audioPlayerReceiver);
		
		//请求者
		KeypadInvoker keypadInvoker = new KeypadInvoker();
		keypadInvoker.setPlayCommand(playCommand);
		keypadInvoker.setRewindCommand(rewindCommand);
		keypadInvoker.setStopCommand(stopCommand);
		
		keypadInvoker.play();
		keypadInvoker.rewind();
		keypadInvoker.play();
		keypadInvoker.stop();
	}
}